package reflection;

import org.junit.Test;
import reflection.entity.Graduate;
import reflection.entity.User;
import reflection.service.MyInterface;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;

/**
 * @author liweimin
 * @date 2021/4/13 10:34
 * @description
 * @since
 */
public class NewReflectionTest {

    public static Class clazz = null;
    public static final String CLASS_NAME = "reflection.entity.Graduate";

    static {
        try {
            clazz = Class.forName(CLASS_NAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test01() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class clazz = Class.forName("reflection.entity.User");
        //获取构造函数
        Constructor constructor = clazz.getConstructor(String.class, Integer.class, String.class);
        //通过指定参数的构造器创建对象的实例
        User user = (User) constructor.newInstance("lwmzzz", 22, "啾咪");
        System.out.println(user);
//        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
//        Constructor[] constructors = clazz.getConstructors();
//        for (Constructor constructor : constructors) {
//            Class[] parameterTypes = constructor.getParameterTypes();
//            System.out.println(constructor);
//        }
    }

    /**
     * 获取完整的类的结构
     */
    @Test
    public void test02() throws ClassNotFoundException {
        Class clazz = Class.forName(CLASS_NAME);
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        for (Class anInterface : clazz.getInterfaces()) {
            System.out.println(anInterface);
        }
        System.out.println(clazz.getSuperclass());

        for (Constructor declaredConstructor : clazz.getDeclaredConstructors()) {

            //获得修饰符 ：什么都不加 是0 [00000]， public  是1[00001] ，private 是 2  [00010]，protected 是 4[0100]，static 是 8 [01000]，final 是 16 [10000]。
            int modifiers = declaredConstructor.getModifiers();

            System.out.println(modifiers);

            System.out.println(declaredConstructor.getName());

            for (Class parameterType : declaredConstructor.getParameterTypes()) {
                System.out.println(parameterType);
            }
            System.out.println(declaredConstructor);
        }
        for (Method declaredMethod : clazz.getDeclaredMethods()) {
            System.out.println(declaredMethod);
        }

    }

    @Test
    public void test03() throws NoSuchMethodException {
        Class clazz = this.getClass();
        for (Field declaredField : clazz.getDeclaredFields()) {
            System.out.println(declaredField.getModifiers());
        }
        Method declaredMethod = clazz.getDeclaredMethod("test01");
        for (Class<?> exceptionType : declaredMethod.getExceptionTypes()) {
            System.out.println(exceptionType);
        }
        System.out.println(declaredMethod.getModifiers());
    }

    @Test
    public void test04() throws ClassNotFoundException {
        Class clazz = Class.forName(CLASS_NAME);

        for (Annotation annotation : clazz.getDeclaredAnnotations()) {
            System.out.println(annotation);
            System.out.println(annotation.annotationType());
            System.out.println(annotation.hashCode());
        }

        //        Field[] declaredFields = clazz.getDeclaredFields();
//        for (Field declaredField : declaredFields) {
//            System.out.println(declaredField);
//            System.out.println(declaredField.getModifiers());
//        }
    }

    @Test
    public void test05() {
        System.out.println(clazz.getPackage());
        System.out.println(clazz.getProtectionDomain());
    }

    @Test
    public void test06() {
        for (TypeVariable typeParameter : clazz.getTypeParameters()) {
//            typeParameter.isAnnotationPresent()
            System.out.println(typeParameter);

        }
    }

    @Test
    public void test07() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Constructor constructor = clazz.getDeclaredConstructor(String.class, Integer.class, String.class, Integer.class);
        Graduate graduate = (Graduate) constructor.newInstance("lwm", 22, "lwmzzz", 21);
        Method saySomething = clazz.getDeclaredMethod("saySomething", String.class);

        //设置为true--->如果使用私有方法,取消java语言访问检查
        saySomething.setAccessible(true);

        saySomething.invoke(graduate, "测试一下");
    }

    @Test
    public void test08() throws Exception {
        Constructor constructor = clazz.getDeclaredConstructor(String.class, Integer.class, String.class, Integer.class);
        Graduate graduate = (Graduate) constructor.newInstance("lwm", 22, "lwmzzz", 21);
        System.out.println(graduate);
        Field stuId = clazz.getDeclaredField("stuId");
        System.out.println(stuId);
        System.out.println(stuId.getName());
        stuId.setAccessible(true);
        stuId.set(graduate, 100);
        System.out.println(graduate);
    }


}
